package com.topisv.tms.utils.yto;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.JAXB;

import org.apache.commons.codec.binary.Base64;
import org.apache.shiro.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.topisv.tms.entity.Consignor;
import com.topisv.tms.entity.Customers;
import com.topisv.tms.entity.EcCorePrintRegion;
import com.topisv.tms.entity.EdiGoodsSku;
import com.topisv.tms.entity.EdiOrder;
import com.topisv.tms.entity.EdiOrderItem;
import com.topisv.tms.entity.ExpressConfigure;
import com.topisv.tms.entity.ExpressStyle;
import com.topisv.tms.entity.WarehouseAddress;
import com.topisv.tms.entity.work.WorkOrder;
import com.topisv.tms.service.ConsignorService;
import com.topisv.tms.service.CustomersService;
import com.topisv.tms.service.EcCorePrintRegionService;
import com.topisv.tms.service.EdiGoodsSkuService;
import com.topisv.tms.service.EdiOrderItemService;
import com.topisv.tms.service.WarehouseAddressService;
import com.topisv.tms.service.account.ShiroDbRealm.ShiroUser;
import com.topisv.tms.service.vo.PackItems;
import com.topisv.tms.service.vo.PrinterModel;
import com.topisv.tms.service.vo.PrinterStyleType;
import com.topisv.tms.service.work.WorkOrderService;
import com.topisv.tms.utils.FileOperation;
import com.topisv.tms.utils.PrintModelUtil;
import com.topisv.tms.utils.TimeUtil;
import com.topisv.tms.utils.print.PackFormUtil;

/**
 * 圆通电子面单打印（新）
 * @author huwenjun
 *
 */
public class YTOMailUtil {
	
	private static final Logger log = LoggerFactory.getLogger(YTOMailUtil.class);
	
	/**
	 * 请求链接
	 */
	private static String requestUrl = "http://service.yto56.net.cn/CommonOrderModeBServlet.action";
//	private static String requestUrl = "http://58.32.246.71:8000/CommonOrderModeBPlusServlet.action";
	/**
	 * 请求端账号
	 */
	private static String clientId = "K210302679";//"K21000119";//"K210302679";//"K87185744";
	/**
	 * 商家秘钥
	 */
	private static String partnerId = "3H74IuGK";//"u2Z1F7Fh";//3H74IuGK
	@Autowired
	private WorkOrderService workOrderService;
	@Autowired
	private ConsignorService consignorService;
	@Autowired
	private CustomersService customersService;
	@Autowired
	private WarehouseAddressService warehouseAddressService;
	@Autowired
	private EcCorePrintRegionService ecCorePrintRegionService;
	@Autowired
	private EdiOrderItemService ediOrderItemService;
	@Autowired
	private EdiGoodsSkuService ediGoodsskuService;
	
	public static YTOResponse postYTO(EdiOrder e,WarehouseAddress wa,ExpressConfigure expressConfigure) throws Exception {
		clientId = expressConfigure.getAccount();
		partnerId = expressConfigure.getPassword();
		requestUrl = expressConfigure.getUrl();
//		拼接请求参数
		String xmlContent = createMessageInfo(e,wa);
		URL url = new URL(requestUrl);
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setDoOutput(true);
		connection.setRequestMethod("POST");
		OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
		//加密
		MessageDigest messagedigest = MessageDigest.getInstance("MD5");
		messagedigest.update((xmlContent + partnerId).getBytes("UTF-8"));
		byte[] abyte0 = messagedigest.digest();
		String data_digest = new String(Base64.encodeBase64(abyte0));
		//查询
		String queryString = "logistics_interface=" + URLEncoder.encode(xmlContent, "UTF-8")
				+ "&data_digest="+ URLEncoder.encode(data_digest,"UTF-8")
				+ "&clientId=" + URLEncoder.encode(clientId, "UTF-8");
		out.write(queryString);
		out.flush();
		out.close();
		//获取服务端的反馈
		String responseString = "";
		String strLine = "";
		InputStream in = connection.getInputStream();
		BufferedReader reader = new BufferedReader(new InputStreamReader(in));
		while ((strLine = reader.readLine()) != null) {
			responseString += strLine + "\n";
		}
		in.close();
		
//		ResponseMessageVO rm = new ResponseMessageVO();
		YTOResponse rm = new YTOResponse();
		//转换响应对象内容
		rm = JAXB.unmarshal(new StringReader(responseString), YTOResponse.class);
		if("true".equals(rm.getSuccess())){
			log.info("=============请求圆通面单成功=================");
			return rm;
		}else{
			throw new Exception("=============请求圆通面单失败==============");
		}
	}
	
	/**
	 * 创建报文信息
	 * @param e		订单信息
	 * @param wa	仓库地址
	 * @return		String
	 * @throws Exception
	 */
	public static String createMessageInfo(EdiOrder e,WarehouseAddress wha) throws Exception{
		StringBuilder xmlBuilder = new StringBuilder();
		xmlBuilder.append("<RequestOrder>");
		xmlBuilder.append("    <clientID>"+clientId+"</clientID>");
		xmlBuilder.append("    <logisticProviderID>YTO</logisticProviderID>");
		xmlBuilder.append("    <customerId>"+clientId+"</customerId>");
		xmlBuilder.append("    <txLogisticID>"+e.getOrdeno()+"</txLogisticID>");
		xmlBuilder.append("    <tradeNo>1</tradeNo>");
		xmlBuilder.append("    <totalServiceFee>1</totalServiceFee>");
		xmlBuilder.append("    <codSplitFee>1</codSplitFee>");
		xmlBuilder.append("    <orderType>1</orderType>");
		xmlBuilder.append("    <serviceType>1</serviceType>");
		xmlBuilder.append("    <flag>1</flag>");
		xmlBuilder.append("    <sendStartTime>"+e.getScheduleStartTime()+"</sendStartTime>");
		xmlBuilder.append("    <sendEndTime>"+e.getScheduleEndTime()+"</sendEndTime>");
		xmlBuilder.append("    <goodsValue>1</goodsValue>");
		xmlBuilder.append("    <itemsValue>1</itemsValue>");
		xmlBuilder.append("    <insuranceValue>1</insuranceValue>");
		xmlBuilder.append("    <special>1</special>");
		xmlBuilder.append("    <remark></remark>");
		xmlBuilder.append("    <deliverNo>1</deliverNo>");
		xmlBuilder.append("    <type>1</type>");
		xmlBuilder.append("    <totalValue>1</totalValue>");
		xmlBuilder.append("    <itemsWeight>1</itemsWeight>");
		xmlBuilder.append("    <packageOrNot>1</packageOrNot>");
		xmlBuilder.append("    <orderSource>1</orderSource>");
		xmlBuilder.append("    <sender>");
		xmlBuilder.append("        <name>"+wha.getContact()+"</name>");
		xmlBuilder.append("        <postCode></postCode>");
		xmlBuilder.append("        <phone></phone>");
		xmlBuilder.append("        <mobile>"+wha.getMobile()+"</mobile>");
		xmlBuilder.append("        <prov>"+wha.getProvName()+"</prov>");
		xmlBuilder.append("        <city>"+wha.getCityName()+","+wha.getDistName()+"</city>");
		xmlBuilder.append("        <address>"+wha.getAddress()+"</address>");
		xmlBuilder.append("    </sender>");
		xmlBuilder.append("    <receiver>");
		xmlBuilder.append("        <name>"+e.getRecena()+"</name>");
		xmlBuilder.append("        <postCode></postCode>");
		xmlBuilder.append("        <phone>"+e.getTeleph()+"</phone>");
		xmlBuilder.append("        <mobile>"+e.getMobile()+"</mobile>");
		xmlBuilder.append("        <prov>"+e.getProvna()+"</prov>");
		xmlBuilder.append("        <city>"+e.getCityna()+","+e.getDistna()+"</city>");
		xmlBuilder.append("        <address>"+e.getAddres()+"</address>");
		xmlBuilder.append("    </receiver>");
		xmlBuilder.append("    <items>");
		xmlBuilder.append("        <item>");
		xmlBuilder.append("            <itemName>"+e.getBz()+"</itemName>");
		xmlBuilder.append("            <number>"+e.getSkuQty()+"</number>");
		xmlBuilder.append("            <itemValue>0</itemValue>");
		xmlBuilder.append("        </item>");
//		xmlBuilder.append("        <item>");
//		xmlBuilder.append("            <itemName>0a4e51b9-5616-4feb-b8a8-d2e1ba24401f</itemName>");
//		xmlBuilder.append("            <number>2</number>");
//		xmlBuilder.append("            <itemValue>50</itemValue>");
//		xmlBuilder.append("        </item>");
		xmlBuilder.append("    </items>");
		xmlBuilder.append("</RequestOrder>");
		
		return xmlBuilder.toString();
	}
	
	/**
	 * 获得打印快递单所需要的信息
	 * 
	 * @param shippedOrder
	 * @param index
	 * @return
	 * @throws UnsupportedEncodingException 
	 * @throws Exception
	 */
	private <T extends PrinterModel> T getExpressStyleModel(T pm,EdiOrder ediOrder) throws UnsupportedEncodingException {

			ShiroUser curUser = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
			if (null!=curUser) {
				pm.setOperator(curUser.username);
			}
			String ordeno = ediOrder.getOrdeno();
			Customers customers = customersService.findByCustomerCode(ediOrder.getCustomerCode());
			Consignor consignor = consignorService.findCustomersId(customers.getId());
			
			/*if("SF".equals(ediOrder.getCacode()))
			{*/
				pm.setDestCode(ediOrder.getDestCode());
			/*}else {
				//获取城市邮编的前三位数字
				Area areaProv = areaService.findByAreaName2(ediOrder.getProvna());
				if(areaProv!=null){
					Area areaCity = areaService.findByAreaNameAndParentId(ediOrder.getCityna(), areaProv.getId());
					if(areaCity!=null&&areaCity.getZipCode()!=null&&areaCity.getZipCode().length()>=3){
						pm.setDestCode(areaCity.getZipCode().substring(0,3));
					}
				}
			}*/
			pm.setOriginCode(ediOrder.getOriginCode());
			pm.setWaybillNo(ediOrder.getMailNo());
			// 收件人信息
			pm.setToAddress(ediOrder.getAddres().replace("\"", " "));
			pm.setToPhone(ediOrder.getTeleph());
			pm.setToName(ediOrder.getRecena());
			pm.setToMobile(ediOrder.getMobile());
			pm.setToProvince(ediOrder.getProvna());
			pm.setToCity(ediOrder.getCityna());
			pm.setToTowns(ediOrder.getDistna());
			pm.setDestination(ediOrder.getProvna());
			pm.setOrdeno(ordeno);
			pm.setToZipcode(ediOrder.getPostco());
			pm.setPayTime(TimeUtil.getNowDateStringDD(ediOrder.getCrtime()));
			pm.setFromno(ediOrder.getFromno());
			pm.setCustomerOrdeno(ediOrder.getCustomerOrdeno());
			
			// 商品信息
			pm.setPostFee(ediOrder.getPosfee() + "");
			pm.setAllCost(ediOrder.getActuallyPaid() + "");
			pm.setNumber(ediOrder.getSkuQty() + "");
			pm.setBunick(ediOrder.getBunick());//会员昵称
			pm.setExpressNo(ediOrder.getMailNo());
			
			pm.setCompanyCode(ediOrder.getCacode());
			pm.setCompanyName(ediOrder.getCaname());
			pm.setShopName(ediOrder.getShopna());
			pm.setBz(ediOrder.getRemark());
			pm.setBillProvideSiteName(ediOrder.getShmemo());	//运单发放站点
			//pm.setDestination(ediOrder.getRemark());
 
			//大头笔
			pm.setToDistCode(ediOrder.getToShortAddress());
			pm.setShortAddress(ediOrder.getToShortAddress());
			//设置仓库地址
			WarehouseAddress warehouseAddress = warehouseAddressService.findByWarehouseCode(ediOrder.getWarehouseCode());
			if(warehouseAddress != null){
				pm.setWarehouseAddress(warehouseAddress.getAddress());
				pm.setWarehouseContact(warehouseAddress.getContact());
				pm.setWarehouseMobile(warehouseAddress.getMobile());
			}
			WorkOrder workOrder = workOrderService.loadByAnyOrderno(ordeno);
			if(workOrder != null){
				pm.setTaskName(new StringBuilder().append(ediOrder.getBatchTaskCode()).append("_").append(ediOrder.getBackupTaskCode()).append("_").append(workOrder.getRankno()).toString());
				pm.setRankno(workOrder.getRankno());
				pm.setStockInfo(workOrder.getStockInfo());
			}
			try {
				List<EcCorePrintRegion> ecCorePrintRegions=ecCorePrintRegionService.findByAreaName(ediOrder.getCityna());
				if(ecCorePrintRegions.isEmpty()){
					pm.setTitleName(ediOrder.getCityna());
				}else if(ecCorePrintRegions.size()==1){
					pm.setTitleName(ecCorePrintRegions.get(0).getTitleName());
				}else{
					EcCorePrintRegion ecCorePrintRegion=ecCorePrintRegionService.findByAreaNameAndLayers(ediOrder.getProvna(), 1);
					if(ecCorePrintRegion==null){
						pm.setTitleName(ediOrder.getCityna());
					}else{
						for(EcCorePrintRegion epr:ecCorePrintRegions){
							if(epr.getFullName().indexOf(ediOrder.getProvna())==0){
								pm.setTitleName(epr.getTitleName());
								break;
							}else{
								pm.setTitleName(ediOrder.getCityna());
							}
						}
					}
				}
			} catch (Exception e) {
				
			}
			
			List<EdiOrderItem> ediOrderItems = ediOrderItemService.findByCustomerCodeAndOrdeno(ediOrder.getCustomerCode(), ordeno);
			List<PackItems> packItems = new ArrayList<PackItems>();
			int orderItems = ediOrderItems.size()>3?3:ediOrderItems.size();
			int tempTotol=0;//计算一个订单包含的商品总数
			for (int j = 0; j < orderItems; j++) {
				EdiOrderItem ediOrderItem = ediOrderItems.get(j);
				PackItems packItem = new PackItems();
				packItem.setPrice(ediOrderItem.getPri() + "");
				packItem.setPay(ediOrderItem.getPay() + "");
				packItem.setDis(ediOrderItem.getDis() + "");
				packItem.setAmo(ediOrderItem.getAmo() + "");
				packItem.setNumber(ediOrderItem.getQty() + "");
				tempTotol+=ediOrderItem.getQty();
				packItem.setItemName(ediOrderItem.getNam());
				packItem.setPromotion(ediOrderItem.getPro() + "");
				packItem.setFormat(ediOrderItem.getSiz());
				packItem.setSkuNumber(ediOrderItem.getSku());// 货号
				packItem.setItemCode(ediOrderItem.getSku());// 货号
				packItem.setArticleNumber(ediOrderItem.getArticleNumber());
				packItems.add(packItem);
			}
			if(ediOrderItems.size()>3){
				for(int j=3;j<ediOrderItems.size();j++){
					EdiOrderItem ediOrderItem = ediOrderItems.get(j);
					tempTotol+=ediOrderItem.getQty();
				}
			}
			pm.setTotalSkuNumber(tempTotol+"");
			pm.setPackItems(packItems);
			
			String weight = "";
			String length = "";//长度 cm
			String width = ""; //宽 cm
			String height = "";//高 cm
			if(workOrder != null)
			{
				float _weight=0;
				for(EdiOrderItem item : ediOrderItems)
				{
					EdiGoodsSku ediGoodsSku=ediGoodsskuService.findByCustomerCodeAndSku(workOrder.getCustomerCode(), item.getSku());
					if(null == ediGoodsSku)
					{
						continue;
					}
					_weight += (ediGoodsSku.getWeight()==null?0:ediGoodsSku.getWeight())+(ediGoodsSku.getWeightPkg()==null?0:ediGoodsSku.getWeightPkg());
					if("single".equals(ediOrder.getOrderType()) && "MID".equals(workOrder.getCustomerCode()))
					{
						length = Float.parseFloat(ediGoodsSku.getLen())/10 + "cm";
						width = Float.parseFloat(ediGoodsSku.getWid())/10 + "cm";
						height = Float.parseFloat(ediGoodsSku.getHei())/10 + "cm";
					}
					if("multiple".equals(ediOrder.getOrderType()) && "MID".equals(workOrder.getCustomerCode()))
					{
						if("1".equals(ediGoodsSku.getSellFlg()))
						{
							length = Float.parseFloat(ediGoodsSku.getLen())/10 + "cm";
							width = Float.parseFloat(ediGoodsSku.getWid())/10 + "cm";
							height = Float.parseFloat(ediGoodsSku.getHei())/10 + "cm";
						}
					}
				}
				weight = _weight/1000 + "kg";
				pm.setWeight(weight);
				pm.setLength(length);
				pm.setWidth(width);
				pm.setHeight(height);
				
			}
			
			// 寄件人信息
			if(consignor!=null){
				pm.setFromAddress(consignor.getAddress());
				pm.setFromName(consignor.getName());
				pm.setFromPhone(consignor.getPhone());
				pm.setFromMobile(consignor.getMobile());
				pm.setFromCompany(consignor.getAddress());
				pm.setOrigin(consignor.getDistrict());
				pm.setFromZipcode(consignor.getZipcode());
				pm.setFromCity(consignor.getCity());
				pm.setFromTowns(consignor.getDistrict());
			}
			return pm;
	}
	
	private PrinterStyleType getPrinterStyleType(PrinterModel printerModel,ExpressStyle expressStyle) throws Exception {
		String contentString = null;
		try {
			PrinterStyleType printerStyleType = new PrinterStyleType();
        	String expressContent = FileOperation.readerContent(expressStyle.getStyleContent());// 转化的时候
            if("normal".equals(expressStyle.getType())){
    			contentString = PrintModelUtil.replaceParams(expressContent,printerModel);
            }else if("mail".equals(expressStyle.getType())){
    			contentString = PackFormUtil.replaceParams(expressContent, printerModel);

            }
            contentString= contentString.replace("'", "\\'").replaceAll("\"", "'");
			printerStyleType.setContent(contentString);
			printerStyleType.setCompanyCode(expressStyle.getLogisticsCompany().getCompanyCode());
			printerStyleType.setCompanyName(expressStyle.getLogisticsCompany().getCompanyName());
			printerStyleType.setTaskName(printerModel.getTaskName());
			printerStyleType.setRankno(printerModel.getRankno());
			printerStyleType.setOrdeno(printerModel.getOrdeno());
			printerStyleType.setTime(printerModel.getPayTime());
			printerStyleType.setFromno(printerModel.getFromno());
			printerStyleType.setExpressNo(printerModel.getExpressNo()); //KK no
			return printerStyleType;
		} catch (Exception e) {
			throw e;
		}
	}
	public PrinterStyleType getPrinterStyleType(EdiOrder ediOrder,ExpressStyle expressStyle)throws Exception{
		try {
			PrinterModel printerModel = new PrinterModel();
			getExpressStyleModel(printerModel,ediOrder);
			return getPrinterStyleType(printerModel,expressStyle);
		} catch (Exception e) {e.printStackTrace();
			throw e;
		}
	}
}
